<?php
/**
 * openssl 工具提供了许多加解密算法，这里为方便做了几个封装
 *
 * !涉及到公私钥的加密方式，出于安全考虑其加解密方法和密钥不应同时存在于一个文件
 * !产品发布时应分离加解密方法，并把公钥、私钥写到逻辑控制代码里
 *
 * @author xyma
 *
 */
class SslHelper
{
/**
	 * 使用公钥加密字符串
	 *
	 * @param mixed bool|sealed text
	 */
	public static function rsa_encode($source)
	{
		if(!$source){
			return false;
		}
		$pbkey	=	self::publicKey();
		$sealed	=	null;
		$stub	=	null;
		try{
			$result	=	openssl_seal($source, $sealed, $stub, array($pbkey));
		}
		catch(Exception $_e){
			return false;
		}
		if(!$result){
			return false;
		}
		openssl_free_key($pbkey);
		return chunk_split(sprintf('%s!%s', base64_encode($sealed), base64_encode($stub[0])));
	}
	
	/**
	 * 使用私钥解密公钥加密的字符串
	 *
	 * @param mixed bool|source string
	 */
	public static function rsa_decode($sealed_text)
	{
		if(false===strpos($sealed_text,'!')){
			return false;
		}
		list($sealed, $stub)	=	explode('!', $sealed_text);
		$stub	=	base64_decode($stub);
		$sealed	=	base64_decode($sealed);
		$source	=	null;
		$pvkey	=	self::privateKey();
		try{
			$result	=	openssl_open($sealed, $source, $stub, $pvkey);
		}
		catch(Exception $_){
			return false;
		}
		if(!$result){
			return false;
		}
		openssl_free_key($pvkey);
		return $source;
	}
	
	/**
	 * 数字签名
	 */
	public static function sign($source)
	{
		$pvkey	=	self::privateKey();
		$sign_r	=	null;
		try{
			$r		=	openssl_sign($source, $sign_r, $pvkey);
		}
		catch(Exception $_){
			return false;
		}
		openssl_free_key($pvkey);
		return $r ? base64_encode($sign_r) : false;
	}
	
	/**
	 * 验证签名
	 */
	public static function verify($source, $signature)
	{
		$pbkey	=	self::publicKey();
		try{
			$r		=	openssl_verify($source, base64_decode($signature), $pbkey);
		}
		catch(Exception $_){
			return false;
		}
		openssl_free_key($pbkey);
		return $r ? true : false;
	}
	
	
	private static function publicKey()
	{
		return openssl_get_publickey(
<<<STR
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDiNGjpt9IWgiyPQvIcXBACINDZ
RjfYvAyJR1SJbo3uoP5c7AuTuInINxTzT3UWfVSKY3EzHt+rDTstUEji+MhehTEF
qgEg62uKOsyrpom0E8aYflOmqVG34v2Zl43qs0Lp0p1TzfdYIuoogapsYeNQ6Jth
BUxy1VXwZ/wwOF7g9QIDAQAB
-----END PUBLIC KEY-----
STR
		);
	}
	private static function privateKey()
	{
		return openssl_get_privatekey(
<<<STR
-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQDiNGjpt9IWgiyPQvIcXBACINDZRjfYvAyJR1SJbo3uoP5c7AuT
uInINxTzT3UWfVSKY3EzHt+rDTstUEji+MhehTEFqgEg62uKOsyrpom0E8aYflOm
qVG34v2Zl43qs0Lp0p1TzfdYIuoogapsYeNQ6JthBUxy1VXwZ/wwOF7g9QIDAQAB
AoGAbkGtgX4f4OjCX3H6IOiexOrJ4Z3gSrweQCuMgRBqDg5a7WAApJgmUHjItW/d
WoDsXCfsXUaHLxDb71JatIce4kjOXYDIC6KVENJW4ZHDGlKQOhWf4n1FWc2/MdWW
zoGH7H8IFMQT1b3A6VQoVgdDXJmald91j1UAO6t4rXPHYQECQQD273dFfexjUkID
wnBWMDGoJbQbStcXX0ZqS3D3jAzkSyqNzE2ycCuNhpsmDb+PvTzALYNWwnMSefq0
TzjQ8r/dAkEA6oIheQxOSJ8/0jGhHm7Tehjv4VHVbVcbWA4I6k7lf81Brm/MoTJ3
pW1/NmnhddDoIx1H9qNE2oUlf/dkrfif+QJAIw11Gdk5MBQiKNR2C9YFhn/rpCAo
jjnJDhetboZj4hhFbyF8OgMwO4PLDEjRU38iW4laZnttyEambuf8AbUjxQJBAIS0
9XpJ43cnX3d0jGfrcZNzzzPkGnJQy/GNp6/oy+kB37x2GgfSxnCAQXAqhOMmQGe2
p0XEaS98D5eWCYyF2QkCQAFvLBKeHZqvZhZvY2/U1vw3Eotaa/q+03nx7pchGPmH
gqJNh5pVAvOnfpR1slOBnNQZbYwJ2bG1hUG6zg5qcFo=
-----END RSA PRIVATE KEY-----
STR
		);
	}
	
	/** 可用于双向加密的加密 */
	public function mc_encode($str,$key)
	{
		try{
			$td		=	mcrypt_module_open('twofish', '', 'ecb', '');
			mcrypt_generic_init($td,
				substr(md5($key), 0, mcrypt_enc_get_key_size($td)),
				mcrypt_create_iv(mcrypt_enc_get_iv_size($td), MCRYPT_RAND)
			);
			$enc	=	mcrypt_generic($td, strlen($str)."|{$str}");
			mcrypt_module_close($td);
			return base64_encode($enc);
		}
		catch(Exception $_){
			return false;
		}
	}
	/** 可用于双向加密的解密 */
	public function mc_decode($str,$key)
	{
		try{
			$td		=	mcrypt_module_open('twofish', '', 'ecb', '');
			mcrypt_generic_init($td,
				substr(md5($key), 0, mcrypt_enc_get_key_size($td)),
				mcrypt_create_iv(mcrypt_enc_get_iv_size($td), MCRYPT_RAND)
			);
			$dec = mdecrypt_generic($td, base64_decode($str));
			mcrypt_generic_deinit($td);
			mcrypt_module_close($td);
			list($size, $dec)	=	explode('|', $dec);
			return substr($dec, 0, $size);
		}
		catch(Exception $_){
			return false;
		}
	}
}
